package com.uam.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.Feature;
import com.uam.common.exception.CustomException;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Objects;

/**
 * @author uam
 * @create 2023/12/5 15:45
 * @email uam@uam.com
 */
@Slf4j
public class HttpUtils<T> {
    // GET请求
    public static JSONObject get(String url, JSONObject params) {
        CloseableHttpClient httpClient = HttpClientBuilder.create().build();
        String sendUrl = url;
        // 拼接参数
        if (Objects.nonNull(params) && params.size() > 0) {
            sendUrl = connectParams(url, params);
        }
        HttpGet httpGet = new HttpGet(sendUrl);
        CloseableHttpResponse response = null;
        try {
            response = httpClient.execute(httpGet);
            HttpEntity httpEntity = response.getEntity();

            if (HttpStatus.SC_OK == response.getStatusLine().getStatusCode() && null != httpEntity) {
                String string = EntityUtils.toString(httpEntity);
                JSONObject jsonObject = JSON.parseObject(string);
                return jsonObject.getJSONObject("data");
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                close(httpClient, response);
            } catch (IOException e) {
                e.printStackTrace();
                log.error("调用数据失败 url:{}",sendUrl,e);
            }
        }
        throw new CustomException("调用GET请求失败！");
    }

    /**
     * @param url:
     * @param params:
     * @param requestBody: json 串
     * @Description: POST 请求
     * @Author: zzc
     * @Date: 2022-12-16 16:48
     * @return: java.lang.String
     **/
    public static String post(String url, JSONObject params, String requestBody) {
        CloseableHttpClient httpClient = HttpClientBuilder.create().build();
        String sendUrl = url;
        // 1.拼接参数
        if (Objects.nonNull(params) && params.size() > 0) {
            sendUrl = connectParams(url, params);
        }
        HttpPost httpPost = new HttpPost(sendUrl);
        httpPost.setHeader("Content-Type", "application/json;charset=utf8");
        CloseableHttpResponse response = null;
        try {
            // 2.设置request-body
            if (StringUtils.isNotBlank(requestBody)) {
                ByteArrayEntity entity = new ByteArrayEntity(requestBody.getBytes(StandardCharsets.UTF_8));
                entity.setContentType("application/json");
                httpPost.setEntity(entity);
            }
            response = httpClient.execute(httpPost);
            HttpEntity httpEntity = response.getEntity();
            if (HttpStatus.SC_OK == response.getStatusLine().getStatusCode() && null != httpEntity) {
                return EntityUtils.toString(httpEntity);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                close(httpClient, response);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        throw new CustomException("调用POST请求失败！");
    }

    private static String connectParams(String url, JSONObject params) {
        StringBuffer buffer = new StringBuffer();
        buffer.append(url).append("?");
        params.forEach((x, y) -> buffer.append(x).append("=").append(y).append("&"));
        buffer.deleteCharAt(buffer.length() - 1);
        return buffer.toString();
    }

    public static void close(CloseableHttpClient httpClient, CloseableHttpResponse httpResponse) throws IOException {
        if (null != httpClient) {
            httpClient.close();
        }
        if (null != httpResponse) {
            httpResponse.close();
        }
    }

    // GET请求
    public static JSONObject getData(String url, JSONObject params) {
        log.info("url:{}, param:{}",url,JSONObject.toJSONString(params));
        CloseableHttpClient httpClient = HttpClientBuilder.create().build();
        String sendUrl = url;
        // 拼接参数
        if (Objects.nonNull(params) && params.size() > 0) {
            sendUrl = connectParams(url, params);
        }
        HttpGet httpGet = new HttpGet(sendUrl);
        RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(10000 * 6 * 10).setConnectTimeout(10000 * 6 * 10).build();
        httpGet.setConfig(requestConfig);
        CloseableHttpResponse response = null;
        try {
            response = httpClient.execute(httpGet);
            HttpEntity httpEntity = response.getEntity();
            if (null != httpEntity) {
                String data=  EntityUtils.toString(httpEntity);
                return  JSON.parseObject(data).getJSONObject("data");
            }
        } catch (IOException e) {
            e.printStackTrace();
            log.error("调用数据失败 url:{}",sendUrl,e);
        } finally {
            try {
                close(httpClient, response);
            } catch (IOException e) {
                e.printStackTrace();
                log.error("调用数据失败 url:{}",sendUrl,e);
            }
        }
        throw new CustomException("调用GET请求失败！");
    }

    // GET请求
    public static <T> List<T> getDataArray(String url, JSONObject params, Class c) {
        CloseableHttpClient httpClient = HttpClientBuilder.create().build();
        String sendUrl = url;
        // 拼接参数
        if (Objects.nonNull(params) && params.size() > 0) {
            sendUrl = connectParams(url, params);
        }
        HttpGet httpGet = new HttpGet(sendUrl);
        RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(10000 * 6 * 10).setConnectTimeout(10000 * 6 * 10).build();
        httpGet.setConfig(requestConfig);
        CloseableHttpResponse response = null;
        try {
            log.info("请求url:{}",sendUrl);
            response = httpClient.execute(httpGet);
            HttpEntity httpEntity = response.getEntity();
            if (HttpStatus.SC_OK == response.getStatusLine().getStatusCode() && null != httpEntity) {
                String data=  EntityUtils.toString(httpEntity);
                JSONObject jsonObject= JSON.parseObject(data);
                return JSONObject.parseArray(JSON.toJSONString(jsonObject.getJSONArray("data")),c);
            }
        } catch (IOException e) {
            e.printStackTrace();
            log.error("调用远程接口失败 url:{}",sendUrl,e);
        } finally {
            try {
                close(httpClient, response);
            } catch (IOException e) {
                e.printStackTrace();
                log.error("关闭数据流失败 url:{}",sendUrl,e);
            }
        }
        throw new CustomException("调用远程接口失败！");
    }
}
